﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MvcPaging;
using zichan.Entity;
using zichan.DAL;
namespace zichan.BLL
{
    public class CabinetManageService
    {
        public static IPagedList<PutawayServer> List(string name, string Ip, int? machineRoomId, int? serverPurposeClassId, string keyWord, string code, string uNO, int? vacancy, int? companyId, int? statu, int? cabinetId, int? isNull,int? serverSubId, int pageIndex, int pageSize)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                IQueryable<PutawayServer> s = db.PutawayServers;
                if (isNull.HasValue)
                    s = s.Where(o => o.Statu < 2 && o.Vacancy != 0);
                if (!string.IsNullOrEmpty(name))
                {
                    List<int> cIds = db.Cabinets.Where(o => o.Name.Contains(name)).Select(o => o.Id).ToList();
                    s = s.Where(o => cIds.Contains(o.CabinetId));
                }
                if (!string.IsNullOrEmpty(Ip))
                {
                    List<int> ids = db.IPs.Where(o => o.Ip.Contains(Ip)).Select(o => o.Id).ToList();
                    s = s.Where(o => o.IPId.HasValue && ids.Contains(o.IPId.Value) || (ids.Count(p => o.SubIPIds.Contains(p.ToString())) > 0));
                    //方法2
                    //List<int> ipIds = s.Where(o => ids.Contains(o.IPId)).Select(o => o.Id).ToList();
                    //foreach(int i in ids)
                    //{
                    //    string id = i.ToString();
                    //    List<int> subIds=s.Where(o => o.SubIPIds.Contains(id)).Select(o => o.Id).ToList();
                    //    ipIds.AddRange(subIds);
                    //}
                    //s = s.Where(o => ipIds.Contains(o.Id));
                }
                if (machineRoomId.HasValue)
                    s = s.Where(o => o.MachineRoomId == machineRoomId.Value);
                if (serverPurposeClassId.HasValue)
                    s = s.Where(o => o.serverPurposeId == serverPurposeClassId);
                if (serverSubId.HasValue)
                    s = s.Where(o => o.serverPurposeSubId == serverSubId);
                if (!string.IsNullOrEmpty(keyWord))
                {
                    List<int> cIds = db.Cabinets.Where(o => o.Remark.Contains(keyWord)).Select(o => o.Id).ToList();
                    s = s.Where(o => o.Remark.Contains(keyWord) || cIds.Contains(o.CabinetId));
                }
                if (!string.IsNullOrEmpty(code))
                    s = s.Where(o => o.Code.Contains(code));
                if (!string.IsNullOrEmpty(uNO))
                {
                    int u = Int32.Parse(uNO);
                    s = s.Where(o => o.UseNumber == u);
                }
                if (vacancy.HasValue)
                {
                    if (vacancy.Value == 0)
                    {
                        s = s.Where(o => o.Vacancy == 0);
                    }
                    else
                    {
                        s = s.Where(o => o.Vacancy > 0);
                    }
                }
                if (companyId.HasValue)
                    s = s.Where(o => o.CompanyId == companyId.Value);
                if (statu.HasValue)
                    s = s.Where(o => o.Statu == statu.Value);
                if (cabinetId.HasValue)
                    s = s.Where(o => o.CabinetId == cabinetId);
                List<PutawayServer> list = s.OrderBy(o => o.Statu).ThenByDescending(o => o.CabinetUploadTime).ThenByDescending(o => o.putAwayTime).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                List<int> mIds = list.Select(o => o.MachineRoomId).ToList();
                var mNames = db.MachineRooms.Where(o => mIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });
                List<int> cabinetIds = list.Select(o => o.CabinetId).ToList();
                var cabinetNames = db.Cabinets.Where(o => cabinetIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });
                List<int> companyIds = list.Where(o => o.CompanyId.HasValue).Select(o => o.CompanyId.Value).ToList();
                var companyNames = db.CompanyClasses.Where(o => companyIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });

                foreach (PutawayServer p in list)
                {
                    p.MachineRoomName = mNames.FirstOrDefault(o => o.Id == p.MachineRoomId).Name;
                    p.CabinetName = cabinetNames.FirstOrDefault(o => o.Id == p.CabinetId).Name;
                    if (p.serverPurposeId.HasValue)
                        p.serverPurposeName = ServerPurposeService.Get(p.serverPurposeId.Value).serverPurposeName;
                    if (p.serverPurposeSubId.HasValue)
                        p.serverPurposeSubName = ServerPurposeSubClassService.Get(p.serverPurposeSubId.Value).serverPurposeSubName;
                    if (p.IPId.HasValue)
                        p.IP = IPService.Get(p.IPId.Value).Ip;
                    if (!string.IsNullOrEmpty(p.Property))
                    {
                        p.Code = p.Code + "-" + p.Property;
                    }
                    if (!string.IsNullOrEmpty(p.TProperty))
                    {
                        p.Code = p.Code + "-" + p.TProperty;
                    }
                    if (!string.IsNullOrEmpty(p.SubIPIds))
                    {
                        List<string> subIps = new List<string>();
                        List<string> subIpIds = p.SubIPIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                        foreach (string sp in subIpIds)
                        {
                            int id = Int32.Parse(sp);
                            string ip = IPService.Get(id).Ip;
                            subIps.Add(ip);
                        }
                        p.SubIP = string.Join(",", subIps);
                    }
                    if (companyNames.Count() > 0 && p.CompanyId.HasValue)
                        p.CompanyName = companyNames.FirstOrDefault(o => o.Id == p.CompanyId).Name;
                    if (p.Statu == 0)
                    {
                        p.StatuName = "空闲";
                    }
                    if (p.Statu == 1)
                    {
                        p.StatuName = "上架";
                    }
                    if (p.Statu == 2)
                    {
                        p.StatuName = "下架";
                    }
                }
                return list.OrderBy(o=>o.Statu).ThenByDescending(o => o.CabinetUploadTime).ThenByDescending(o => o.putAwayTime).ToPagedList(pageIndex - 1, pageSize, s.Count());
            }
        }
        public static string AddCabinet(Cabinet model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    if (db.Cabinets.Count(o => o.Name == model.Name && o.MachineRoomId == model.MachineRoomId) > 0)
                        return "该机柜已存在，无法添加";
                    db.Cabinets.Add(model);
                    db.SaveChanges();
                    PutawayServer server = new PutawayServer();
                    server.MachineRoomId = model.MachineRoomId;
                    server.CabinetId = model.Id;
                    server.Vacancy = model.Number;
                    server.CabinetUploadTime = model.uploadTime;
                    server.Statu = 0;
                    server.IsInverse = true;
                    db.PutawayServers.Add(server);
                    db.SaveChanges();
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "添加失败";
                }
            }
        }
        public static Cabinet GetCabinet(int id)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                return db.Cabinets.Where(o => o.Id == id).FirstOrDefault();
            }
        }
        public static string EditCabinet(Cabinet model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    if (db.Cabinets.Count(o => model.Id != o.Id && o.MachineRoomId == model.MachineRoomId && o.Name == model.Name) > 0)
                        return "该机柜已存在，无法编辑";
                    int oldNO = GetCabinet(model.Id).Number;
                    PutawayServer put = db.PutawayServers.Where(o => o.CabinetId == model.Id&&o.Statu==0).FirstOrDefault();
                    if (oldNO != model.Number||put.Vacancy!=model.Number)
                    {
                       
                        put.Vacancy = model.Number;
                        db.Entry(put).State = System.Data.Entity.EntityState.Modified;
                        db.SaveChanges();
                    }
                    db.Entry(model).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法编辑";
                }

            }
        }
        public static string AddPutAway(PutawayServer model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    if (db.Assets.Count(o => o.AssetClassId == 1 && o.Code.Trim() == model.Code.Trim() && o.Status == 2) <= 0)
                        return "该服务器编码错误，无法添加,请确认该编码在库存中且已进行使用设置";
                    if (db.PutawayServers.Count(o => o.Statu == 1 && o.Code.Trim() == model.Code.Trim()) > 0)
                        return "该服务器编码已使用";
                    model.SubIPIds = string.Join(",", model.SubIPId);
                    model.Vacancy = model.Vacancy - model.UseNumber;
                    if (db.PutawayServers.Count(o => o.CabinetId == model.CabinetId && o.Statu == 0) == 1)
                    {
                        int id = db.PutawayServers.FirstOrDefault(o => o.CabinetId == model.CabinetId && o.Statu == 0).Id;
                        PutawayServer server = db.PutawayServers.FirstOrDefault(o => o.Id == id);
                        server.SubIPIds = model.SubIPIds;
                        server.Vacancy = model.Vacancy;
                        server.Property = model.Property;
                        server.CompanyId = model.CompanyId;
                        //server.PurposeId = model.PurposeId;
                        server.serverPurposeId = model.serverPurposeId;
                        server.serverPurposeSubId = model.serverPurposeSubId;
                        server.Code = model.Code;
                        server.UseNumber = model.UseNumber;
                        server.IPId = model.IPId;
                        server.IntranetIP = model.IntranetIP;
                        server.IsInverse = model.IsInverse;
                        server.Remark = model.Remark;
                        server.putAwayTime = DateTime.Now;
                        server.Statu = 1;
                        db.Entry<PutawayServer>(server).State = System.Data.Entity.EntityState.Modified;
                        db.SaveChanges();
                        db.Database.ExecuteSqlCommand("update PutawayServers set Vacancy={0} where CabinetId={1}", model.Vacancy, model.CabinetId);

                    }
                    else
                    {
                        Cabinet cabinet = GetCabinet(model.CabinetId);
                        model.CabinetUploadTime = cabinet.uploadTime;
                        model.putAwayTime = DateTime.Now;
                        model.Statu = 1;
                        db.PutawayServers.Add(model);
                        db.SaveChanges();
                        //string sql = "update PutawayServers set Vacancy=" + model.Vacancy + " where CabinetId=" + model.CabinetId;
                        //db.Database.SqlQuery<PutawayServer>(sql);
                        db.Database.ExecuteSqlCommand("update PutawayServers set Vacancy={0} where CabinetId={1}", model.Vacancy, model.CabinetId);
                    }
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法上架";
                }
            }
        }
        public static List<Cabinet> CabinetList(int machineRoomId)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                return db.Cabinets.Where(o => o.MachineRoomId == machineRoomId && !o.IsDelete.HasValue).ToList();
            }
        }
        public static PutawayServer Get(int id)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                PutawayServer model = db.PutawayServers.FirstOrDefault(o => o.Id == id);
                model.MachineRoomName = MachineRoomService.Get(model.MachineRoomId).Name;
                model.CabinetName = CabinetManageService.GetCabinet(model.CabinetId).Name;
                //model.CompanyName = CompanyClassService.GetCompany(model.CompanyId.Value).Name;

                return model;
            }
        }
        public static string EditPutAway(PutawayServer model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    if (db.Assets.Count(o => o.AssetClassId == 1 && o.Code.Trim() == model.Code.Trim() && o.Status == 2) <= 0)
                        return "该服务器编码错误，无法添加,请确认该编码在库存中且已进行使用设置";
                    if (db.PutawayServers.Count(o => o.Code.Trim() == model.Code.Trim() && o.Id != model.Id && o.Statu == 1) > 0)
                        return "该服务器编码已使用";
                    int oldUseNumber = Get(model.Id).UseNumber.Value;
                    if (oldUseNumber != model.UseNumber)
                    {
                        model.Vacancy = model.Vacancy + oldUseNumber - model.UseNumber;
                    }
                    db.Entry(model).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
                    if (oldUseNumber != model.UseNumber)
                    {
                        db.Database.ExecuteSqlCommand("update PutawayServers set Vacancy={0} where CabinetId={1}", model.Vacancy, model.CabinetId);
                    }

                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法修改";
                }
            }
        }
        public static string RemoveCabinet(int id)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    if (db.PutawayServers.Count(o => o.CabinetId == id) > 0)
                        return "该机柜正在使用，无法删除";
                    Cabinet model = GetCabinet(id);
                    PutawayServer put = db.PutawayServers.Where(o => o.CabinetId == id).FirstOrDefault();
                    db.Cabinets.Remove(model);
                    db.PutawayServers.Remove(put);
                    db.SaveChanges();
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法删除";
                }
            }
        }
        public static List<int> useNO(int cabinetId)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                int ableUse = db.PutawayServers.Where(o => o.CabinetId == cabinetId).Select(o => o.Vacancy.Value).FirstOrDefault();
                List<int> number = new List<int>();
                for (int i = 1; i <= ableUse; i++)
                {
                    number.Add(i);
                }
                return number;
            }
        }
        public static void U_Number(out int number, out int noUse, int cabinetId)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                number = GetCabinet(cabinetId).Number;
                noUse = db.PutawayServers.Where(o => o.CabinetId == cabinetId).Select(o => o.Vacancy.Value).FirstOrDefault();

            }
        }
        public static string OutOfRockEdit(PutawayServer model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    model.Vacancy = model.Vacancy + model.UseNumber;
                    db.Entry(model).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
                    db.Database.ExecuteSqlCommand("update PutawayServers set Vacancy={0} where CabinetId={1}", model.Vacancy, model.CabinetId);
                    if (model.Statu == 2 && db.PutawayServers.Count(o => o.CabinetId == model.CabinetId && (o.Statu == 1)) <= 0)
                    {
                        PutawayServer server = new PutawayServer();
                        server.MachineRoomId = model.MachineRoomId;
                        server.CabinetId = model.CabinetId;
                        server.Vacancy = model.Vacancy;
                        server.CabinetUploadTime = model.CabinetUploadTime;
                        server.Statu = 0;
                        server.IsUsed = 1;
                        server.IsInverse = true;
                        db.PutawayServers.Add(server);
                        db.SaveChanges();

                    }

                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法下架";
                }
            }
        }
        public static string CancellationCabinet(Cabinet model)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                try
                {
                    db.Entry(model).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();
                    CabinetUseLog log = new CabinetUseLog();
                    log.Time = DateTime.Now;
                    log.cabinetId = model.Id;
                    log.Operation = "报废机柜：" + model.Name;
                    CabinetUseLogService.Add(log);
                    MachineRoomLogService.Add(3, log.Operation);
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return "无法报废";
                }
            }
        }
        public static string RemovePutAwayServer(int id)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {

                PutawayServer model = db.PutawayServers.FirstOrDefault(o => o.Id == id);
                db.PutawayServers.Remove(model);
                db.SaveChanges();
                return string.Empty;
            }
        }
        public static List<string> IPs(string ids)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                List<string> Ips = new List<string>();
                if (!string.IsNullOrEmpty(ids))
                {
                    List<int> id = Array.ConvertAll<string, int>(ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => int.Parse(s)).ToList();
                    Ips = db.IPs.Where(o => id.Contains(o.Id)).Select(o => o.Ip).ToList();
                }
                return Ips;
            }
        }
        public static List<PutawayServer> List(string name, string Ip, int? machineRoomId, int? serverPurposeClassId, int? serverPurposeClassSubId, string keyWord, string code, string uNO, int? vacancy, int? companyId, int? isNull, int? statu, int? cabinetId)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                IQueryable<PutawayServer> s = db.PutawayServers;
                if (isNull.HasValue)
                    s = s.Where(o => o.Statu < 2 && o.Vacancy != 0);
                if (!string.IsNullOrEmpty(name))
                {
                    List<int> cIds = db.Cabinets.Where(o => o.Name.Contains(name)).Select(o => o.Id).ToList();
                    s = s.Where(o => cIds.Contains(o.Id));
                }
                if (!string.IsNullOrEmpty(Ip))
                {
                    List<int> ids = db.IPs.Where(o => o.Ip.Contains(Ip)).Select(o => o.Id).ToList();
                    s = s.Where(o => o.IPId.HasValue && ids.Contains(o.IPId.Value) || (ids.Count(p => o.SubIPIds.Contains(p.ToString())) > 0));
                    //方法2
                    //List<int> ipIds = s.Where(o => ids.Contains(o.IPId)).Select(o => o.Id).ToList();
                    //foreach(int i in ids)
                    //{
                    //    string id = i.ToString();
                    //    List<int> subIds=s.Where(o => o.SubIPIds.Contains(id)).Select(o => o.Id).ToList();
                    //    ipIds.AddRange(subIds);
                    //}
                    //s = s.Where(o => ipIds.Contains(o.Id));
                }
                if (machineRoomId.HasValue)
                    s = s.Where(o => o.MachineRoomId == machineRoomId.Value);
                if (serverPurposeClassId.HasValue)
                    s = s.Where(o => o.serverPurposeId == serverPurposeClassId);
                if (serverPurposeClassSubId.HasValue)
                    s = s.Where(o => o.serverPurposeSubId == serverPurposeClassSubId);
                if (!string.IsNullOrEmpty(keyWord))
                {
                    List<int> cIds = db.Cabinets.Where(o => o.Remark.Contains(keyWord)).Select(o => o.Id).ToList();
                    s = s.Where(o => o.Remark.Contains(keyWord) || cIds.Contains(o.CabinetId));
                }
                if (!string.IsNullOrEmpty(code))
                    s = s.Where(o => o.Code.Contains(code));
                if (!string.IsNullOrEmpty(uNO))
                {
                    int u = Int32.Parse(uNO);
                    s = s.Where(o => o.UseNumber == u);
                }
                if (vacancy.HasValue)
                {
                    if (vacancy.Value == 0)
                    {
                        s = s.Where(o => o.Vacancy == 0);
                    }
                    else
                    {
                        s = s.Where(o => o.Vacancy > 0);
                    }
                }
                if (companyId.HasValue)
                    s = s.Where(o => o.CompanyId == companyId.Value);
                if (statu.HasValue)
                    s = s.Where(o => o.Statu == statu.Value);
                if (cabinetId.HasValue)
                    s = s.Where(o => o.CabinetId == cabinetId);
                List<int> mIds = s.Select(o => o.MachineRoomId).ToList();
                var mNames = db.MachineRooms.Where(o => mIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });
                List<int> cabinetIds = s.Select(o => o.CabinetId).ToList();
                var cabinetNames = db.Cabinets.Where(o => cabinetIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });
                List<int> companyIds = s.Where(o => o.CompanyId.HasValue).Select(o => o.CompanyId.Value).ToList();
                var companyNames = db.CompanyClasses.Where(o => companyIds.Contains(o.Id)).Select(o => new { o.Id, o.Name });

                foreach (PutawayServer p in s)
                {
                    p.MachineRoomName = mNames.FirstOrDefault(o => o.Id == p.MachineRoomId).Name;
                    p.CabinetName = cabinetNames.FirstOrDefault(o => o.Id == p.CabinetId).Name;
                    if (p.serverPurposeId.HasValue)
                        p.serverPurposeName =ServerPurposeService.Get(p.serverPurposeId.Value).serverPurposeName;
                    if (p.serverPurposeSubId.HasValue)
                        p.serverPurposeSubName = ServerPurposeSubClassService.Get(p.serverPurposeSubId.Value).serverPurposeSubName;
                    if (p.IPId.HasValue)
                        p.IP = IPService.Get(p.IPId.Value).Ip;

                    if (!string.IsNullOrEmpty(p.SubIPIds))
                    {
                        List<string> subIps = new List<string>();
                        List<string> subIpIds = p.SubIPIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                        foreach (string sp in subIpIds)
                        {
                            int id = Int32.Parse(sp);
                            string ip = IPService.Get(id).Ip;
                            subIps.Add(ip);
                        }
                        p.SubIP = string.Join(",", subIps);
                    }
                    if (companyNames.Count() > 0 && p.CompanyId.HasValue)
                        p.CompanyName = companyNames.FirstOrDefault(o => o.Id == p.CompanyId).Name;
                    if (p.Statu == 0)
                    {
                        p.StatuName = "空闲";

                    }
                    if (p.Statu == 1)
                    {
                        p.StatuName = "上架";
                    }
                    if (p.Statu == 2)
                    {
                        p.StatuName = "下架";
                    }
                }
                return s.OrderByDescending(o => o.CabinetUploadTime).ThenByDescending(o => o.putAwayTime).ToList();
            }
        }
        public static void Count(out int cCount, out int cUseCount, out int cSubCount)
        {
            using (ZichanDBContext db = new ZichanDBContext())
            {
                if (db.Cabinets.Count() <= 0)
                {
                    cCount = 0;
                    cUseCount = 0;
                    cSubCount = 0;
                }
                else {
                    cCount = db.Cabinets.Where(o => !o.IsDelete.HasValue).Sum(o => o.Number);
                    IQueryable<PutawayServer> w = db.PutawayServers.Where(o => o.Statu == 1 && o.UseNumber.HasValue);
                    if (w.Count() > 0)
                        cUseCount = w.Sum(o => o.UseNumber.Value);
                    else
                        cUseCount = 0;
                    cSubCount = cCount - cUseCount;
                }
            }
        }
    }
}
